#include "CToastBox.h"
#include <QTimerEvent>
#include <QTimer>
#include <QEvent>
#include <QPropertyAnimation>
#include <QApplication>
#include <QDesktopWidget>
#include <QPainter>
#include <QFontDatabase>
#include <QPushButton>
#include <QScreen>

#include <QDebug>

#define DEFAULT_WIDTH	500
#define DEFAULT_HEIGHT	300

void CToastBox::Info(QWidget * parent, const QString & title, const QString & content, bool modal,int timeCount)
{
	auto box = new CToastBox(EToastBoxType_Info, parent, title, content, modal);
    box->SetTimeout(timeCount*1000);
	box->show();
}

void CToastBox::Warn(QWidget * parent, const QString & title, const QString & content, bool modal,int timeCount)
{
	auto box = new CToastBox(EToastBoxType_Warn, parent, title, content, modal);
    box->SetTimeout(timeCount*1000);
	box->show();
}

void CToastBox::Error(QWidget * parent, const QString & title, const QString & content, bool modal,int timeCount)
{
	auto box = new CToastBox(EToastBoxType_Error, parent, title, content, modal);
    box->SetTimeout(timeCount*1000);
	box->show();
}

void CToastBox::Success(QWidget * parent, const QString & title, const QString & content, bool modal,int timeCount/* = 1*/)
{
	auto box = new CToastBox(EToastBoxType_Success, parent, title, content, modal);
    box->SetTimeout(timeCount*1000);
	box->show();
}

int CToastBox::Question(QWidget * parent, const QString & title, const QString & content, bool modal,int timeCount/* = 16*/)
{
    auto box = new CToastBox(EToastBoxType_Question, parent, title, content, modal);
    box->SetTimeout(timeCount*1000);
    return box->exec();
}

CToastBox* CToastBox::Wait(QWidget * parent, const QString & title, const QString & content, bool modal)
{
    auto box = new CToastBox(EToastBoxType_Wait, parent, title, content, modal);
    box->SetTimeout(60000);
    box->show();
    return box;
}

bool CToastBox::Enable_icon_ = false;
bool CToastBox::Enable_title_ = false;
bool CToastBox::Enable_mask_ = false;
int CToastBox::Alpha_ = 100;
int CToastBox::Timeout_ = 3000;
CToastBox::CToastBox(EToastBoxType type, QWidget * parent, const QString & title, const QString & content, bool modal)
	: parent_(parent)
	, type_(type)
	, title_(title)
	, content_(content)
	, anima_(0)
    , auto_close_(true)
    , icon_(QPixmap(":/img/toast_icon.png"))
    , bModal_(modal)
{
    if (modal){
//        auto_close_ = false;
		setAttribute(Qt::WA_ShowModal, true);
        setModal(true);
    }else{
//        auto_close_ = true;
        setAttribute(Qt::WA_ShowModal, false);
        setModal(false);
    }

	if (parent != Q_NULLPTR)
	{
		parent_ = parent;
		parent_->installEventFilter(this);
		setParent(parent_);
        resize(parent->size());

        setGeometry(parent->geometry());
        move(parent->mapToGlobal(QPoint(0,0)));
	}
	else
	{
        QScreen *screen = qApp->primaryScreen();
//		setGeometry(QApplication::desktop()->geometry());
//		resize(QApplication::desktop()->size());
        setGeometry(screen->geometry());
        resize(screen->size());
    }

    /// 设置图标
    switch (type)
    {
    case EToastBoxType_Success:
        icon_ = QPixmap(":/images/icon/icon_success.png");
        break;
    case EToastBoxType_Question:
    {
        icon_ = QPixmap(":/images/icon/icon_question.png");
//        m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel,this);
        m_buttonYes = new QPushButton(tr("是"),this);
        m_buttonNo = new QPushButton(tr("否"),this);
        QString sYesStyle = QString(
                    "QPushButton{"
                    "   min-width:120px;"
                    "   min-height:46px;"
                    "   color:white;"
                    "   background-color: #5cb85c;"
                    "   border-color: #4cae4c;"
                    "   border-radius: 5px;"
                    "}"
                    "QPushButton:pressed{"
                    "   background-color: #449d44;"
                    "   border-color: #398439;"
                    "}");
        QString sNoStyle = QString(
                    "QPushButton{"
                    "   min-width:120px;"
                    "   min-height:46px;"
                    "   color:white;"
                    "   background-color: #d9534f;"
                    "   border-color: #ac2925;"
                    "   border-radius: 5px;"
                    "}"
                    "QPushButton:pressed{"
                    "   background-color: #c9302c;"
                    "   border-color: #398439;"
                    "}");
        m_buttonYes->setStyleSheet(sYesStyle);
        m_buttonNo->setStyleSheet(sNoStyle);
        QFont font = m_buttonYes->font();
        font.setPixelSize(26);
        m_buttonYes->setFont(font);
        m_buttonNo->setFont(font);

        connect(m_buttonYes,&QPushButton::clicked,this,&CToastBox::slot_buttonPress);
        connect(m_buttonNo,&QPushButton::clicked,this,&CToastBox::slot_buttonPress);
        break;
    }
    default:
        icon_ = QPixmap(":/images/icon/icon_error.png");
        break;
    }

    setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool);

	setAttribute(Qt::WA_AlwaysStackOnTop, true); 
	setAttribute(Qt::WA_TranslucentBackground, true);

	QPropertyAnimation* anima = new QPropertyAnimation(this, "windowOpacity");
	connect(anima, &QPropertyAnimation::finished, this, &CToastBox::close);
	connect(anima, &QPropertyAnimation::finished, this, &CToastBox::deleteLater);
	anima->setDuration(300);
	anima->setStartValue(1.0);
	anima->setEndValue(0.0);
	anima->setEasingCurve(QEasingCurve::OutQuad);
	anima_ = anima;
}

void CToastBox::timerEvent(QTimerEvent * event)
{
	QWidget::timerEvent(event);
}

void CToastBox::paintEvent(QPaintEvent * event)
{
//    Q_UNUSED(event);
	QPainter painter(this); 
	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
	if (Enable_mask_)
	{
		painter.fillRect(rect(), QColor(0, 0, 0, Alpha_));
	}

	// draw content rect
	QRect rect_main = this->rect();
	QRect rect_content(QPoint(
		rect_main.width() / 2 - DEFAULT_WIDTH / 2,
		rect_main.height() / 2 - DEFAULT_HEIGHT / 2),
		QSize(DEFAULT_WIDTH, DEFAULT_HEIGHT));
	QPainterPath path;
	path.addRoundedRect(rect_content, 20, 20);
    painter.fillPath(path, QColor(0xff, 0xff, 0xff));

    // drawRoundedRect
    painter.setPen(QColor(0x33, 0x33, 0x33,125));
    painter.drawRoundedRect(rect_content,20,20);

	// draw text
	QFont font;
    font.setFamily("Microsoft YaHei");
    font.setPixelSize(24);
	QFontMetrics metrics(font);
	int font_width = metrics.width(content_);
//	int font_height = metrics.height();
	QString str = content_;
	if (font_width > DEFAULT_WIDTH - 60)
	{
        str = metrics.elidedText(content_, Qt::ElideRight, DEFAULT_WIDTH - 60);
	}
	QRect rect_text = QRect(QPoint(
		rect_content.bottomLeft().x() + 30,
        rect_content.bottomLeft().y() - 165),
        QSize(DEFAULT_WIDTH - 60, 150));
    painter.setPen(QColor(0x00, 0x00, 0x00));
	painter.setFont(font);
	painter.drawText(rect_text, content_, QTextOption(Qt::AlignCenter));

	// draw icon
	QRect rect_icon = QRect(QPoint(
		rect_content.topLeft().x() + rect_content.width() / 2 - icon_.width() / 2,
		rect_content.topLeft().y() + 30),
		QSize(icon_.size()));
	painter.drawPixmap(rect_icon, icon_);

    //move buttons
    if(m_buttonYes){
        m_buttonYes->move(QPoint(
                              rect_content.topLeft().x() + rect_content.width() / 2 - m_buttonYes->width()-30,
                              rect_content.topLeft().y() + 240));
    }
    if(m_buttonNo){
        m_buttonNo->move(QPoint(
                             rect_content.topLeft().x() + rect_content.width() / 2 + 30,
                             rect_content.topLeft().y() + 240));
    }

    return QWidget::paintEvent(event);
}

void CToastBox::mousePressEvent(QMouseEvent * event)
{
    auto_close_ = false;
    if(!bModal_){
        if (anima_){
            anima_->start(QPropertyAnimation::DeleteWhenStopped);
        }
    }

	QWidget::mousePressEvent(event);
}

void CToastBox::showEvent(QShowEvent * event)
{
	QTimer::singleShot(Timeout_, this, [this]() {
		if (!auto_close_) return;
		if (anima_)  anima_->start(QPropertyAnimation::DeleteWhenStopped);
	});

	QPropertyAnimation* anima2 = new QPropertyAnimation(this, "windowOpacity");
	anima2->setStartValue(0.0);
	anima2->setEndValue(1.0);
	anima2->setDuration(300);
	anima2->start(QPropertyAnimation::DeleteWhenStopped);
	QWidget::showEvent(event);
}

void CToastBox::closeEvent(QCloseEvent * event)
{
	QWidget::closeEvent(event);
}

bool CToastBox::eventFilter(QObject * watched, QEvent * event)
{
	if (qobject_cast<QWidget*>(watched) == parent_)
	{
		if (event->type() == QEvent::Resize || event->type() == QEvent::Move)
		{
			setGeometry(parent_->geometry());
            move(parent_->mapToGlobal(QPoint(0,0)));
			update();
		}
	}

	return QWidget::eventFilter(watched, event);
}

void CToastBox::slot_buttonPress(){
    QPushButton* pSender = static_cast<QPushButton*>(sender());
    if(!pSender){
        return;
    }

    if(pSender == m_buttonYes){
        accept();
    }else if(pSender == m_buttonNo){
        reject();
    }else{
        reject();
    }

    this->deleteLater();
}
